<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

class Dragonfly_Config implements ArrayAccess
{
	const
		TYPE_STR = 0,
		TYPE_INT = 1;

	protected
		$refresh_cache = false;

	# loads the global configuration system
	function __construct($__set_state=false)
	{
		if ($__set_state) { return; }
		$K = Dragonfly::getKernel();
		// cfg_type
		$result = $K->SQL->query("SELECT cfg_name, cfg_field, cfg_value FROM {$K->SQL->TBL->config_custom} ORDER BY 1, 2");
		if (!$result) { return; }
		while ($row = $result->fetch_row()) {
			if (!isset($this->$row[0])) { $this->$row[0] = new Dragonfly_Config_Section(); }
			$this->$row[0]->$row[1] = trim($row[2]);
		}
		$result->free();

		# Cache everything
		$K->CACHE->set(__CLASS__, $this);
		$this->init();
	}

	public static function load()
	{
		$c = Dragonfly::getKernel()->CACHE->get(__CLASS__);
		return ($c ? $c : new Dragonfly_Config());
	}

	public static function removeFromCache()
	{
		Dragonfly::getKernel()->CACHE->delete(__CLASS__);
	}

	protected function init()
	{
		$this->refresh_cache = false;
		if (!$this->global->timezone) { $this->set('global', 'timezone', 'UTC'); }
		if (empty($_COOKIE['PoodleTimezone'])) date_default_timezone_set($this->global->timezone);
		$this->set('poodle','identity_class', 'Dragonfly_Identity');
	}

	# when class gets destroyed check for changes and delete cache when needed
	function __destruct()
	{
		if ($this->refresh_cache) { self::removeFromCache(); }
	}

	# retrieve section key value
	public function get($section, $key)
	{
		return isset($this->$section->$key) ? $this->$section->$key : null;
	}

	# set value for section key
	public function set($section, $key, $value)
	{
		if (!$section || !$key) { return false; }
		if (!isset($this->$section->$key)) {
			# section key doesn't exist so we create it
			\Poodle\LOG::notice(\Poodle\LOG::CREATE, 'Dragonfly_Config->'.$section.'->'.$key.' did not exist.');
			$this->add($section, $key, $value);
			return;
		}
		// issue: 0=='value' is the same
		if (is_bool($value)) { $value = (int)$value; }
		if ((string)$this->$section->$key === (string)$value) { return; }
		$this->$section->$key = $value;
		$SQL = Dragonfly::getKernel()->SQL;
		$SQL->query('UPDATE '.$SQL->TBL->config_custom.' SET cfg_value='.$SQL->quote($value)." WHERE cfg_name='{$section}' AND cfg_field='{$key}'");
		$this->refresh_cache = true;
	}

	# create a new section key with value
	public function add($section, $key, $value)
	{
		if (isset($this->$section->$key)) { return; }
		if (!isset($this->$section)) { $this->$section = new Dragonfly_Config_Section(); }
		if (is_bool($value)) { $value = (int)$value; }
		$this->$section->$key = $value;
		$SQL = Dragonfly::getKernel()->SQL;
		$SQL->query('INSERT INTO '.$SQL->TBL->config_custom." (cfg_name, cfg_field, cfg_value) VALUES ('{$section}', '{$key}', '".$SQL->escape_string($value)."')");
		$this->refresh_cache = true;
	}

	# destroy section key or whole section
	public function delete($section, $key=false)
	{
		if (!is_object($this->$section)) { return; }
		if (!$key) {
			$this->$section = null;
		} else {
			if (!isset($this->$section->$key)) { return; }
			$this->$section->$key = null;
		}
		$SQL = Dragonfly::getKernel()->SQL;
		$SQL->query('DELETE FROM '.$SQL->TBL->config_custom." WHERE cfg_name='{$section}'".($key ? " AND cfg_field='{$key}'" : ''));
		$this->refresh_cache = true;
	}

/*
	public function __sleep()
	{
		return get_object_vars($this);
	}
*/
	public function __wakeup()
	{
		$this->init();
	}

	// This static method is called for classes exported by var_export()
	public static function __set_state($arr)
	{
		$c = new Dragonfly_Config(true);
		foreach ($arr as $key => $value) { $c->$key = $value; }
		$c->init();
		return $c;
	}

	# ArrayAccess
	public function offsetExists($k)  { return property_exists($this, $k); }
	public function offsetGet($k)     { return $this->$k; }
	public function offsetSet($k, $v) {}
	public function offsetUnset($k)   {}
}

class Dragonfly_Config_Section extends ArrayIterator
{
	// This static method is called for classes exported by var_export()
	public static function __set_state($arr)
	{
		$c = new Dragonfly_Config_Section();
		foreach ($arr as $key => $value) { $c->$key = $value; }
		return $c;
	}

	function __get($k)     { return $this->offsetGet($k); }
	function __isset($k)   { return $this->offsetExists($k); }
	function __unset($k)   { $this->offsetUnset($k); }
	function __set($k, $v) { $this->offsetSet($k, $v); }
}
